﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Kugar.Core.ExtMethod;
using Kugar.Core.Printer;

namespace Kugar.UI.WinForm
{

    [ToolboxBitmap(typeof(DataGridViewDynamicCellTypeColumn), "DataGridViewTextBoxColumn.bmp")]
    public class DataGridViewDynamicCellTypeColumn : DataGridViewColumn
    {
        private DataGridView _currentGrid = null;

        public DataGridViewDynamicCellTypeColumn()
            : base(new DataGridViewDynamicCellTypeCell())
        {
            this.SortMode = DataGridViewColumnSortMode.NotSortable;
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                // Ensure that the cell used for the template is a CalendarCell.
                if (value != null &&
                    !value.GetType().IsAssignableFrom(typeof(DataGridViewDynamicCellTypeCell)))
                {
                    throw new InvalidCastException("Must be a DynamicColumnCell");
                }
                base.CellTemplate = (DataGridViewDynamicCellTypeCell)value;
            }
        }

        protected override void OnDataGridViewChanged()
        {
            base.OnDataGridViewChanged();

            if (_currentGrid != null)
            {
                _currentGrid.ColumnWidthChanged -= dataGridView_ColumnWidthChanged;
                _currentGrid.Scroll -= dataGridView_Scroll;
            }

            if (this.DataGridView != null)
            {
                this.DataGridView.ColumnWidthChanged += dataGridView_ColumnWidthChanged;
                this.DataGridView.Scroll += dataGridView_Scroll;
            }

            _currentGrid = this.DataGridView;

        }

        private void dataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            var target = e.Column.DataGridView;

            target.Invalidate(target.DisplayRectangle);
        }

        private void dataGridView_Scroll(object sender, ScrollEventArgs e)
        {
            _currentGrid.Invalidate(_currentGrid.DisplayRectangle);
        }
    }


    internal class DataGridViewDynamicCellTypeCell : DataGridViewCell
    {
        //private DataGridView _currentDataGrid = null;
        //private DataGridViewDynamicCellTypeColumnEditingControl _currentEditControl = null;
        public DataGridViewDynamicCellTypeCell()
            : base()
        {
        }

        public override Type ValueType
        {
            get
            {
                return typeof(object);
            }
        }

        public override Type EditType
        {
            get
            {
                return typeof(DataGridViewDynamicCellTypeColumnEditingControl);
            }
        }

        public override object DefaultNewRowValue
        {
            get
            {
                return null;
            }
        }

        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            if (!(DataGridView.EditingControl is DataGridViewDynamicCellTypeColumnEditingControl))
            {
                return;
            }

            var ctl = DataGridView.EditingControl as DataGridViewDynamicCellTypeColumnEditingControl;

            //if (initialFormattedValue is Image)
            //{
            //    return;
            //}
            //else
            //{
            
                ctl.Width = this.OwningColumn.Width;
                ctl.Height = this.DataGridView.Rows[rowIndex].Height;
                ctl.Cell = this;
                ctl.Value = initialFormattedValue;

                //_currentEditControl = ctl;
                base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            //}
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            //背景色
            Color clr_background = (cellState & DataGridViewElementStates.Selected) !=
                                   DataGridViewElementStates.Selected
                                       ? cellStyle.BackColor
                                       : cellStyle.SelectionBackColor;



            using (Brush bru = new SolidBrush(clr_background))
            {
                graphics.FillRectangle(bru, cellBounds);
            }

            //边框
            if ((paintParts & DataGridViewPaintParts.Border) != 0)
            {
                PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
            }

            if (value is DBNull || value == null)
            {
                return;
            }


            if (value is Image)
            {
                graphics.DrawImage((Image)value, cellBounds.X, cellBounds.Y, cellBounds.Width, cellBounds.Height);
            }
            else if (value is string || value.GetType().IsNumericType() || value is DateTime)
            {
                var color = (cellState & DataGridViewElementStates.Selected) !=
                            DataGridViewElementStates.Selected
                                ? cellStyle.ForeColor
                                : cellStyle.SelectionForeColor;

                using (var brush = new SolidBrush(color))
                {
                    graphics.DrawString(formattedValue.ToString(), cellStyle.Font, brush, cellBounds);
                }
            }

        }

        //protected override void OnEnter(int rowIndex, bool throughMouseClick)
        //{
        //    //if (!this.OwningColumn.ReadOnly)
        //    //{
        //    //    this.DataGridView.BeginEdit(true);
        //    //}

        //    base.OnEnter(rowIndex, throughMouseClick);

        //}

        //protected override void OnContentClick(DataGridViewCellEventArgs e)
        //{
        //    if (!this.OwningColumn.ReadOnly)
        //    {
        //        this.DataGridView.BeginEdit(true);
        //    }
        //    base.OnContentClick(e);
        //}

        //private void DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        //{

        //    //if (e.ColumnIndex == this.ColumnIndex && _currentEditControl != null)
        //    //{
        //    //    base.SetValue(e.RowIndex, _currentEditControl.Value);
        //    //    _currentEditControl = null;
        //    //}
        //}

        //protected override void OnDataGridViewChanged()
        //{
        //    if (this.DataGridView != _currentDataGrid)
        //    {
        //        if (_currentDataGrid!=null)
        //        {
        //            _currentDataGrid.CellEndEdit -= DataGridView_CellEndEdit;
        //        }

                

        //        this.DataGridView.CellEndEdit += DataGridView_CellEndEdit;
        //    }
        //}


    }



    internal class DataGridViewDynamicCellTypeColumnEditingControl : DynamicValueBox, IDataGridViewEditingControl
    {
        public DataGridViewDynamicCellTypeColumnEditingControl()
            : base()
        {
            base.PropertyChanged += DataGridViewDynamicCellTypeColumnEditingControl_PropertyChanged;
        }

        void DataGridViewDynamicCellTypeColumnEditingControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (this.Cell != null && e.PropertyName == "Value")
            {
                this.IsChanged = true;
                this.Cell.Value = base.Value;
                //((DataGridViewDynamicCellTypeCell)this.Cell).RaiseCellValueChangedInternal();

            }
        }


        #region Implementation of IDataGridViewEditingControl

        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            
        }

        public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
        {
            switch (keyData & Keys.KeyCode)
            {
                case Keys.Left:
                case Keys.Up:
                case Keys.Down:
                case Keys.Right:
                case Keys.Home:
                case Keys.End:
                case Keys.Tab:
                    return true;
                default:
                    return false;
            }
        }

        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            var value = base.Value;

            if (value is DateTime)
            {
                return ((DateTimePicker) this.CurrentControl).Text;
            }
            else if(this.CurrentControl is NumericUpDown)
            {
                return this.CurrentControl.Text;
            }

            return this.Value;
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {

        }

        private DataGridView _editingControlDataGridView;
        public DataGridView EditingControlDataGridView
        {
            get { return _editingControlDataGridView; }
            set
            {
                _editingControlDataGridView = value;
            } 
        }

        public DataGridViewCell Cell { set; get; }

        public object EditingControlFormattedValue
        {
            get
            {
                return this.Value;
            }
            set
            {
                //this.Value =value;
            }
        }

        public int EditingControlRowIndex { get; set; }
        public bool EditingControlValueChanged
        {
            get { return true; }
            set
            {
                //this.IsChanged = true;
            }
        }
        public Cursor EditingPanelCursor { get { return base.Cursor; } }
        public bool RepositionEditingControlOnValueChange { get { return true; } }

        public bool IsChanged { set; get; }

        #endregion
    }

    //[ToolboxBitmap(typeof(DynamicTypeBox)]


    //public class DataGridViewDynamicColumnTextBox : Control
    //{
    //    protected List<TextBox> lstTextbox = new List<TextBox>();
    //    private DynamicColumn _value = null;

    //    public DataGridViewDynamicColumnTextBox()
    //    {

    //    }

    //    public bool IsChanged { set; get; }

    //    public DynamicColumn Value
    //    {
    //        get { return _value; }
    //        set
    //        {
    //            if (_value != value)
    //            {
    //                _value = value;
    //                relayoutTextBox();
    //            }
    //        }
    //    }

    //    protected void relayoutTextBox()
    //    {
    //        int j = 0;

    //        lstTextbox.ForEach(x => x.Visible = false);

    //        var headers = _value.Collection.DynamicColumns[this.Value.GroupName];

    //        if (headers.HeaderTextList.Count <= 0)
    //        {
    //            return;
    //        }

    //        foreach (var column in headers.HeaderTextList)
    //        {
    //            TextBox textbox = null;

    //            if (j < lstTextbox.Count)
    //            {
    //                textbox = lstTextbox[j];
    //            }
    //            else
    //            {
    //                textbox = new TextBox();
    //                textbox.Multiline = false;
    //                textbox.BorderStyle = BorderStyle.FixedSingle;
    //                textbox.BorderStyle = BorderStyle.FixedSingle;
    //                textbox.Enter += textbox_Enter;
    //                lstTextbox.Add(textbox);
    //            }

    //            textbox.TextChanged -= textbox_TextChanged;
    //            textbox.KeyDown -= textbox_KeyDown;

    //            textbox.Tag = column.Key;

    //            if (_value.ContainsKey(column.Key))
    //            {
    //                textbox.Text = _value[column.Key].ToStringEx();
    //            }
    //            else
    //            {
    //                textbox.Text = "";
    //            }

    //            textbox.Visible = true;
    //            this.Controls.Add(textbox);

    //            textbox.TextChanged += textbox_TextChanged;
    //            textbox.KeyDown += textbox_KeyDown;

    //            j += 1;
    //        }

    //        for (int i = 0; i < lstTextbox.Count; i++)
    //        {
    //            var textbox = lstTextbox[i];

    //            textbox.Width = this.Width / lstTextbox.Count;
    //            textbox.Height = this.Height + 1;
    //            textbox.Left = i * textbox.Width;
    //            textbox.Top = 0;
    //        }

    //        lstTextbox[0].Focus();

    //    }

    //    void textbox_Enter(object sender, EventArgs e)
    //    {
    //        var txt = (TextBox)sender;

    //        txt.SelectionStart = 0;
    //        txt.SelectionLength = txt.Text.Length;
    //    }

    //    void textbox_KeyDown(object sender, KeyEventArgs e)
    //    {
    //        if (e.KeyCode == Keys.Tab)
    //        {
    //            var txt = (TextBox)sender;

    //            var index = lstTextbox.IndexOf(txt);

    //            if (index == lstTextbox.Count - 1)
    //            {
    //                index = 0;
    //            }
    //            else
    //            {
    //                index += 1;
    //            }

    //            lstTextbox[index].Focus();
    //        }
    //    }

    //    void textbox_TextChanged(object sender, EventArgs e)
    //    {
    //        var txt = (TextBox)sender;

    //        this.Value[txt.Tag] = txt.Text;

    //        IsChanged = true;
    //    }


    //}
}
